var contextarray = [];

var defaults = {
    html: false,        // Enable HTML tags in source
    xhtmlOut: false,        // Use '/' to close single tags (<br />)
    breaks: false,        // Convert '\n' in paragraphs into <br>
    langPrefix: 'language-',  // CSS language prefix for fenced blocks
    linkify: true,         // autoconvert URL-like texts to links
    linkTarget: '',           // set target to open link in
    typographer: true,         // Enable smartypants and other sweet transforms
    _highlight: true,
    _strict: false,
    _view: 'html'
};
defaults.highlight = function (str, lang) {
    if (!defaults._highlight || !window.hljs) { return ''; }

    var hljs = window.hljs;
    if (lang && hljs.getLanguage(lang)) {
        try {
            return hljs.highlight(lang, str).value;
        } catch (__) { }
    }

    try {
        return hljs.highlightAuto(str).value;
    } catch (__) { }

    return '';
};
mdHtml = new window.Remarkable('full', defaults);

mdHtml.renderer.rules.table_open = function () {
    return '<table class="table table-striped">\n';
};

mdHtml.renderer.rules.paragraph_open = function (tokens, idx) {
    var line;
    if (tokens[idx].lines && tokens[idx].level === 0) {
        line = tokens[idx].lines[0];
        return '<p class="line" data-line="' + line + '">';
    }
    return '<p>';
};

mdHtml.renderer.rules.heading_open = function (tokens, idx) {
    var line;
    if (tokens[idx].lines && tokens[idx].level === 0) {
        line = tokens[idx].lines[0];
        return '<h' + tokens[idx].hLevel + ' class="line" data-line="' + line + '">';
    }
    return '<h' + tokens[idx].hLevel + '>';
};
function getCookie(name) {
    var cookies = document.cookie.split(';');
    for (var i = 0; i < cookies.length; i++) {
        var cookie = cookies[i].trim();
        if (cookie.indexOf(name + '=') === 0) {
            return cookie.substring(name.length + 1, cookie.length);
        }
    }
    return null;
}
// 设置 cookie
function setCookie(name, value, days) {
  var expires = "";
  if (days) {
    var date = new Date();
    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
    expires = "; expires=" + date.toUTCString();
  }
  document.cookie = name + "=" + value + expires + "; path=/";
} 


function isMobile() {
    const userAgent = navigator.userAgent.toLowerCase();
    const mobileKeywords = ['iphone', 'ipod', 'ipad', 'android', 'windows phone', 'blackberry', 'nokia', 'opera mini', 'mobile'];
    for (let i = 0; i < mobileKeywords.length; i++) {
        if (userAgent.indexOf(mobileKeywords[i]) !== -1) {
            return true;
        }
    }
    return false;
}

function insertPresetText() {
    $("#kw-target").val($('#preset-text').val());
    autoresize();
}

function copyToClipboard(text) {
    var input = document.createElement('textarea');
    input.innerHTML = text;
    document.body.appendChild(input);
    input.select();
    var result = document.execCommand('copy');
    document.body.removeChild(input);
    return result;
}

function copycode(obj) {
    copyToClipboard($(obj).closest('code').clone().children('button').remove().end().text());
    layer.msg("复制完成！");
}

function autoresize() {
    var textarea = $('#kw-target');
    var width = textarea.width();
    var content = (textarea.val() + "a").replace(/\\n/g, '<br>');
    var div = $('<div>').css({
        'position': 'absolute',
        'top': '-99999px',
        'border': '1px solid red',
        'width': width,
        'font-size': '15px',
        'line-height': '20px',
        'white-space': 'pre-wrap'
    }).html(content).appendTo('body');
    var height = div.height();
    var rows = Math.ceil(height / 20);
    div.remove();
    textarea.attr('rows', rows);
    $("#article-wrapper").height(parseInt($(window).height()) - parseInt($("#fixed-block").height()) - parseInt($(".layout-header").height()) - 50);
}
function randomString(len) {
	len = len || 32;
	var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';    /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
	var maxPos = $chars.length;
	var pwd = '';
	for (i = 0; i < len; i++) {
		pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
	}
	return pwd;
}
function getParameterByName(name) {
	var url = window.location.href;
	name = name.replace(/[\[\]]/g, '\\$&');
	var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)'),
		results = regex.exec(url);
	if (!results) return null;
	if (!results[2]) return '';
	return decodeURIComponent(results[2].replace(/\+/g, ' '));
}
var totalPage = -1;
var currentPage = 1;
var pageSize = 50;
function toGetHistory(){
	if(totalPage==-1||currentPage<totalPage){
		var sessionId = $socket.getStorage("sessionId");
		if(!sessionId){
			sessionId = getParameterByName("sessionId");
			if(sessionId){
				$socket.setStorage("sessionId",sessionId);
			}else{
				return;
			}
		}
		var param = {};
		param.type="history"; 
		if(sessionId){
			param.sessionId=sessionId;
		}
		param.pageIndex=currentPage;
		param.pageSize=pageSize;
		var requsetData = {};
		requsetData.url = "ChatGPTWork";
		requsetData.queryData = param;
		$socket.send(requsetData,({status,res})=> {
			if(status){ 
				if(res.state){ 
					var page = res.body.data;
					if(page.totalCount==0){
						console.log('无历史记录');
						return;
					}
					totalPage = page.totalPage;
					var list = page.list;
					for(var i = 0 ; i < list.length;i++){
						var question = list[i].question;
						var answer = mdHtml.render(list[i].answer);
						var answerId = randomString(16);
						$("#article-wrapper").append('<li class="article-title"><pre>'+question+'</pre></li>');
						$("#article-wrapper").append('<li class="article-content" id="'+answerId+'">'+answer+'</li>');
						$("#" + answerId + " pre code").each(function () {
						    $(this).html("<button onclick='copycode(this);' class='codebutton'>复制</button>" + $(this).html());
						}); 
					}
					MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
					document.getElementById("article-wrapper").scrollTop = 100000;
					currentPage++;
				}else{
					layer.msg("加载历史记录失败，请点击历史对话查看！"+res.msg);
				}
				
			}else{
				 layer.msg("加载历史记录失败，请点击历史对话查看！");
			}
		});
	}else{
		console.log("没有更多了，无需加载");
	}
}
$(document).ready(function () { 
      autoresize();
	  toGetHistory();
	  // 监听div的滚动事件
	  $('#article-wrapper').scroll(function() {
	    // 判断滚动条是否滑到顶部
	    if ($(this).scrollTop() === 0) {
	      // 滑到顶部的逻辑处理 
		  toGetHistory();
	    }
	  });
 
	 $socket.init(function(status,msg){
		if(status){ 
		}else{
			 layer.msg("与服务器连接异常:"+msg);
		}
	 });
	 $socket.message(function(res){
		console.log(res);
	 })

    $("#kw-target").on('keydown', function (event) {
        if (event.keyCode == 13 && event.ctrlKey) {
            send_post();
            return false;
        }
    });

    $(window).resize(function () {
        autoresize();
    });

    $('#kw-target').on('input', function () {
        autoresize();
    });

    $("#ai-btn").click(function () {
        if ($("#kw-target").is(':disabled')) {
            clearInterval(timer);
            $("#kw-target").val("");
            $("#kw-target").attr("disabled", false);
            autoresize();
            $("#ai-btn").html('<i class="iconfont icon-wuguan"></i>发送');
            if (!isMobile()) $("#kw-target").focus();
        } else {
            send_post();
        }
        return false;
    });

    $("#clean").click(function () {
        $("#article-wrapper").html("");
        $socket.rmStorage("sessionId");
        layer.msg("已开启新的对话，想继续之前的对话，可在历史对话中找到并点击‘继续该对话’按钮");
		var newUrl = "http://youdelu.fun:10005/chatgpt/";
		window.history.pushState({}, '', newUrl);
		return false;
    });
	$("#history").click(function () {  
        var url = "http://youdelu.fun:10005/page/page-c8f5db2a-0dd3-4554-988f-475c6f54b3f6.html";
		window.open(url);
        return false;
    });
	$("#share").click(function () {
		var sessionId = $socket.getStorage("sessionId");
		if(sessionId){
			 var url = "http://youdelu.fun:10005/chatgpt/?sessionId="+sessionId; 
			 copyToClipboard(url);
			  layer.msg("已复制分享链接到剪切板,发给你的朋友即可看到当前的聊天内容");
		}else{
			 layer.msg("当前对话为空！");
		}
	    return false;
	});

    $("#showlog").click(function () {
        let btnArry = ['已阅'];
        layer.open({ type: 1, title: '全部对话日志', area: ['80%', '80%'], shade: 0.5, scrollbar: true, offset: [($(window).height() * 0.1), ($(window).width() * 0.1)], content: '<iframe src="chat.txt?' + new Date().getTime() + '" style="width: 100%; height: 100%;"></iframe>', btn: btnArry });
        return false;
    });

    function send_post() {
        var prompt = $("#kw-target").val();

        if (prompt == "") {
            layer.msg("请输入您的问题", { icon: 5 });
            return;
        }

        var loading = layer.msg('正在组织语言，请稍等片刻...', {
            icon: 16,
            shade: 0.4,
            time: false //取消自动关闭
        }); 
		var isstarted = true;
		var alltext = "";
		var isalltext = false;
		
		var sessionId = $socket.getStorage("sessionId");
		var param = {};
		param.type="chat";
		param.message=prompt;
		if(sessionId){
			param.sessionId=sessionId;
		}
		var requsetData = {};
		requsetData.url = "ChatGPTWork";
		requsetData.queryData = param;
		$socket.send(requsetData,({status,res})=> {
			if(status){ 
				var state = res.state;
				var data = res.body; 
				//成功
				if(state){
					if(data.sessionId){  
						$socket.setStorage("sessionId",data.sessionId);
						return;
					}
					var complete = res.complete; 
					if (isstarted) {
					    layer.close(loading);
					    $("#kw-target").val("请耐心等待AI把话说完……");
					    $("#kw-target").attr("disabled", true);
					    autoresize();
					    $("#ai-btn").html('<i class="iconfont icon-wuguan"></i>中止');
					    layer.msg("处理成功！");
					    isstarted = false;
					    answer = randomString(16);
					    $("#article-wrapper").append('<li class="article-title" id="q' + answer + '"><pre></pre></li>');
					    for (var j = 0; j < prompt.length; j++) {
					        $("#q" + answer).children('pre').text($("#q" + answer).children('pre').text() + prompt[j]);
					    }
					    $("#article-wrapper").append('<li class="article-content" id="' + answer + '"></li>');
					    let str_ = '';
					    let i = 0;
					    let strforcode = '';
					    timer = setInterval(() => {
					        let newalltext = alltext;
					        let islastletter = false;
					        //有时服务器错误地返回\\n作为换行符，尤其是包含上下文的提问时，这行代码可以处理一下。
					        if (newalltext.split("\n").length == 1) {
					            newalltext = newalltext.replace(/\\n/g, '\n');
					        }
					        if (str_.length < (newalltext.length - 3)) {
					            str_ += newalltext[i++];
					            strforcode = str_;
					            if ((str_.split("```").length % 2) == 0) {
					                strforcode += "\n```\n";
					            } else {
					                strforcode += "_";
					            }
					        } else {
					            if (isalltext) {
					                clearInterval(timer);
					                strforcode = newalltext;
					                islastletter = true;
					                $("#kw-target").val("");
					                $("#kw-target").attr("disabled", false);
					                autoresize();
					                $("#ai-btn").html('<i class="iconfont icon-wuguan"></i>发送');
					                if (!isMobile()) $("#kw-target").focus();
					            }
					        }
					    
					        newalltext = mdHtml.render(strforcode); 
					        $("#" + answer).html(newalltext);
					        if (islastletter) MathJax.Hub.Queue(["Typeset", MathJax.Hub]); 
					        $("#" + answer + " pre code").each(function () {
					            $(this).html("<button onclick='copycode(this);' class='codebutton'>复制</button>" + $(this).html());
					        });
					        document.getElementById("article-wrapper").scrollTop = 100000;
					    }, 5);
					}
					
					//完成
					if(complete){
						isalltext = true; 
					}else{
						 if (alltext == "") {
							 alltext = data.replace(/^\n+/, ''); //去掉回复消息中偶尔开头就存在的连续换行符
						 } else {
							 alltext += data;
						 }
					}
				}else{
					//失败
					switch (data) {
					    case "invalid_api_key":
					        layer.msg("API-KEY不合法");
					        break;
					    case "context_length_exceeded":
					        layer.msg("问题和上下文长度超限，请重新提问");
					        break;
					    case "rate_limit_reached":
					        layer.msg("同时访问用户过多，请稍后再试");
					        break;
					    case "access_terminated":
					        layer.msg("违规使用，API-KEY被封禁");
					        break;
					    case "no_api_key":
					        layer.msg("未提供API-KEY");
					        break;
					    case "insufficient_quota":
					        layer.msg("API-KEY余额不足");
					        break;
					    case "account_deactivated":
					        layer.msg("账户已禁用");
					        break;
					    case "model_overloaded":
					        layer.msg("OpenAI模型超负荷，请重新发起请求");
					        break;
					    case null:
					        layer.msg("OpenAI服务器访问超时或未知类型错误");
					        break;
					    default:
					        layer.msg("OpenAI服务器故障，错误类型：" + data);
					} 
					if (!isMobile()) $("#kw-target").focus();
					return;
				}
			}else{
				 layer.msg(res);
			}
		}); 
    }
});
